package io.gitee.zhangbinhub.admin.init

import io.gitee.zhangbinhub.acp.boot.init.AcpInitialization
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.conf.AcpOauthServerAutoConfiguration
import io.gitee.zhangbinhub.admin.constant.DbConstant
import io.gitee.zhangbinhub.admin.constant.RoleCode
import io.gitee.zhangbinhub.admin.constant.WorkFlowConstant
import io.gitee.zhangbinhub.admin.service.ApplicationService
import io.gitee.zhangbinhub.admin.service.InitDataService
import io.gitee.zhangbinhub.admin.service.RoleService
import io.gitee.zhangbinhub.admin.service.UserService
import org.springframework.core.io.ClassPathResource
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Component
import java.nio.file.Files

@Component
class DataInitialization(
    private val logAdapter: LogAdapter,
    private val applicationService: ApplicationService,
    private val userService: UserService,
    private val roleService: RoleService,
    private val initDataService: InitDataService,
    private val acpOauthServerAutoConfiguration: AcpOauthServerAutoConfiguration,
    private val jdbcTemplate: JdbcTemplate
) : AcpInitialization {
    override val name: String
        get() = "Data Initialization"

    override val order: Int
        get() = 1

    private fun initTable() {
        ClassPathResource(
            "${DbConstant.SCHEMA_PATH}/${
                jdbcTemplate.dataSource?.connection?.metaData?.databaseProductName?.lowercase()
            }/${WorkFlowConstant.SCHEMA_FILE}"
        ).let { resource ->
            Files.readString(resource.file.toPath(), CommonTools.getDefaultCharset())
        }.apply {
            for (sql in this.split(";")) {
                if (sql.trim { it <= ' ' }.length > 10) {
                    jdbcTemplate.execute(sql)
                }
            }
        }
    }

    private fun initData() {
        applicationService.getAppList().apply {
            if (this.isEmpty()) {
                logAdapter.info(">>>>>>>>>>>>>>>>>>>> begin init system resource data...")
                initDataService.doInitResources()
                logAdapter.info(">>>>>>>>>>>>>>>>>>>> init system resource data has finished!")
            }
            acpOauthServerAutoConfiguration.loadClientInfo()
        }
        userService.getUserVoListByRole(listOf(RoleCode.SUPER)).apply {
            if (this.isEmpty()) {
                logAdapter.info("admin user is not existed")
                logAdapter.info("begin init admin user...")
                roleService.getRoleList().filter { role -> role.code == RoleCode.SUPER }.let { roleList ->
                    initDataService.initAdminUser(roleList)
                }
                logAdapter.info("init admin user has finished!")
            }
        }
    }

    override fun doInit() {
        initTable()
        initData()
    }
}